module ElementaryMath
    implicit none

contains
    pure function Quadratic(a, b, c, x) result (v)
        implicit none
        real(kind=8), intent(in) :: a, b, c, x
        real(kind=8) :: v
        v = a * x **2.0d0 + b * x + c
    end function


    function RootQuadratic(a, b, c, y) result (r)
        implicit none
        real(kind=8), intent(in) :: a, b, c
        real(kind=8), optional, intent(in) :: y

        real(kind=8), dimension(2) :: r
        real(kind=8) :: aux

        if (present(y)) then
            aux = c - y
            r(1) = (-b - sqrt(b**2.0d0-4.0d0*a*aux))/2.0d0/a
            r(2) = (-b + sqrt(b**2.0d0-4.0d0*a*aux))/2.0d0/a
        else
            r(1) = (-b - sqrt(b**2.0d0-4.0d0*a*c))/2.0d0/a
            r(2) = (-b + sqrt(b**2.0d0-4.0d0*a*c))/2.0d0/a
        end if
    end function


    pure function Linear(a, b, x) result (v)
        implicit none
        real(kind=8), intent(in) :: a,b,x
        real(kind=8) :: v
        v = a * x + b
    end function


    function RootLinear(a, b, y) result (v)
        implicit none
        real(kind=8), intent(in) :: a, b
        real(kind=8), optional, intent(in) :: y
        real(kind=8) :: v
        if(present(y)) then
            v = (y-b)/a
        else
            v = -b/a
        end if
	end function
end module
